package com.haredot.config;

import com.github.hiwepy.qqwry.spring.boot.ext.QQWry;
import com.haredot.filter.BearerTokenAuthorizationFilter;
import com.haredot.filter.JWTAuthenticationFilter;
import com.haredot.properties.JwtProperties;
import com.haredot.security.HaredotAccessDeniedHandler;
import com.haredot.security.HaredotAuthenticationFailureHandler;
import com.haredot.security.HaredotAuthenticationSuccessHandler;
import com.haredot.security.JsonAuthenticationEntryPoint;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.cors.CorsConfiguration;

import javax.annotation.Resource;
import java.util.List;


@EnableWebSecurity
@Configuration
@EnableMethodSecurity
@EnableConfigurationProperties(JwtProperties.class)
public class SecurityConfig{

    @Resource
    private JwtProperties jwtProperties;

    @Resource
    private UserDetailsService userDetailsService;

    @Resource
    private RabbitTemplate rabbitTemplate ;

    @Resource
    private QQWry qqWry ;

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        // 拦截所有的请求，必须登录后才能访问
        http.authorizeHttpRequests()
                .antMatchers("/preview", "/swiper/getSwipersAndAdvert").permitAll()
                .anyRequest()
                .authenticated();

        // 当用户没有认证的时候(默认会弹出登录页面 配合formLogin) , 注入一个自定义的AuthenticationEntryPoint对象，返回符合项目要求的效果
        http.exceptionHandling()
                .accessDeniedHandler(new HaredotAccessDeniedHandler()) // 处理403 禁止访问错误
                .authenticationEntryPoint(new JsonAuthenticationEntryPoint());

        http.csrf().disable(); // 禁用 CSRF 保护

        http.cors()
                .configurationSource(request -> {
                    CorsConfiguration corsConfiguration = new CorsConfiguration();
                    corsConfiguration.setAllowedOriginPatterns(List.of("*"));
                    corsConfiguration.setAllowedMethods(List.of("*"));
                    corsConfiguration.setAllowedHeaders(List.of("*"));
                    return corsConfiguration;
                });  // 指定跨域请求的配置

        http.formLogin()
                .loginProcessingUrl("/api/token")
                .failureHandler(new HaredotAuthenticationFailureHandler(qqWry, rabbitTemplate))
                .successHandler(new HaredotAuthenticationSuccessHandler(jwtProperties, rabbitTemplate, qqWry));

        // 配置 session 创建策略 STATELESS 适用于 前后端分离
        http.sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS);


        http.addFilterBefore(new BearerTokenAuthorizationFilter(jwtProperties), UsernamePasswordAuthenticationFilter.class);
        // 添加过滤器
        http.addFilterBefore(new JWTAuthenticationFilter(userDetailsService, jwtProperties), UsernamePasswordAuthenticationFilter.class);

        return http.build();
    }

}
